import { useState, useCallback, useMemo } from 'react'

export interface UseSelectionOptions {
  /** 是否多选 */
  multiple?: boolean
  /** 初始选中项 */
  initialSelected?: string[]
}

/**
 * useSelection Hook
 * 单选/多选管理
 */
export const useSelection = ({ multiple = true, initialSelected = [] }: UseSelectionOptions = {}) => {
  const [selected, setSelected] = useState<string[]>(initialSelected)

  /**
   * 选择项
   */
  const select = useCallback(
    (id: string) => {
      if (multiple) {
        setSelected((prev) => (prev.includes(id) ? prev : [...prev, id]))
      } else {
        setSelected([id])
      }
    },
    [multiple]
  )

  /**
   * 取消选择项
   */
  const deselect = useCallback((id: string) => {
    setSelected((prev) => prev.filter((item) => item !== id))
  }, [])

  /**
   * 切换选择状态
   */
  const toggle = useCallback(
    (id: string) => {
      if (selected.includes(id)) {
        deselect(id)
      } else {
        select(id)
      }
    },
    [selected, select, deselect]
  )

  /**
   * 判断是否选中
   */
  const isSelected = useCallback(
    (id: string): boolean => {
      return selected.includes(id)
    },
    [selected]
  )

  /**
   * 批量选择
   */
  const selectMultiple = useCallback(
    (ids: string[]) => {
      if (multiple) {
        setSelected((prev) => {
          const newSelected = new Set([...prev, ...ids])
          return Array.from(newSelected)
        })
      } else {
        setSelected(ids.slice(0, 1))
      }
    },
    [multiple]
  )

  /**
   * 批量取消选择
   */
  const deselectMultiple = useCallback((ids: string[]) => {
    setSelected((prev) => prev.filter((id) => !ids.includes(id)))
  }, [])

  /**
   * 全选
   */
  const selectAll = useCallback((allIds: string[]) => {
    if (multiple) {
      setSelected(allIds)
    }
  }, [multiple])

  /**
   * 取消全选
   */
  const clearSelection = useCallback(() => {
    setSelected([])
  }, [])

  /**
   * 反选
   */
  const invertSelection = useCallback((allIds: string[]) => {
    if (multiple) {
      setSelected((prev) => {
        const currentSet = new Set(prev)
        return allIds.filter((id) => !currentSet.has(id))
      })
    }
  }, [multiple])

  /**
   * 设置选中项
   */
  const setSelection = useCallback((ids: string[]) => {
    setSelected(ids)
  }, [])

  // 派生状态
  const selectedCount = useMemo(() => selected.length, [selected])
  const hasSelection = useMemo(() => selected.length > 0, [selected])
  const isAllSelected = useCallback(
    (allIds: string[]) => {
      return allIds.length > 0 && allIds.every((id) => selected.includes(id))
    },
    [selected]
  )
  const isPartialSelected = useCallback(
    (allIds: string[]) => {
      const selectedSet = new Set(selected)
      const selectedFromAll = allIds.filter((id) => selectedSet.has(id))
      return selectedFromAll.length > 0 && selectedFromAll.length < allIds.length
    },
    [selected]
  )

  return {
    // 状态
    selected,
    selectedCount,
    hasSelection,

    // 单项操作
    select,
    deselect,
    toggle,
    isSelected,

    // 批量操作
    selectMultiple,
    deselectMultiple,
    selectAll,
    clearSelection,
    invertSelection,
    setSelection,

    // 状态判断
    isAllSelected,
    isPartialSelected,
  }
}

export default useSelection

